package wassalt.client;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.*;
import android.widget.ListView;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.*;
import wassalt.Utils.*;

public class RequestsListActivity extends ListActivity {

	DbAdapter db;
	ListAdapter la;
	public ListView lv;
	Cursor c;
	int tab_id;
	ProgressDialog dialog;
	IncomingReceiver icr;
	IntentFilter filter;

	/**
	 * Here the database is initiated and according to the current tab the
	 * corresponding table contents are fetched and viewed as a list
	 * 
	 * @author Aya Kamel
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		// Instantiating the incoming receiver and adding filters
		icr = new IncomingReceiver();
		filter = new IntentFilter();
		filter.addAction(AppConstants.UPDATE_TABLES);

		// Get the bundle which contains the current tab id
		Bundle bundle = getIntent().getExtras();
		if(bundle!=null)
			tab_id = bundle.getInt("tab_id");
		else
			tab_id=0;

		// Initiate the database and fetch the corresponding table contents
		db = new DbAdapter(this);
		if (!db.isOpened)
			db.open();
		c = db.fetchAllNotifications(tab_id);
		db.close();
		la = new ListAdapter(this, c, tab_id);
		setListAdapter(la);

		// View the table in a list view
		lv = getListView();

		// Set the onClick listener for the list items
		lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> arg0, View v, int pos,
					long id) {
				itemClick(v, pos, id);
			}
		});

		// Set the onLongClick listener for the list items
		registerForContextMenu(lv);
		lv.setTextFilterEnabled(true);
	}

	/**
	 * @author Aya Kamel
	 * @param v
	 *            The view of the selected item
	 * @param pos
	 *            The id of the selected item
	 */
	private void itemClick(View v, int pos, long id) {
		if (v != null) {
			TextView info1 = (TextView) v.findViewById(R.id.info1);
			TextView info2 = (TextView) v.findViewById(R.id.info2);
			TextView info3 = (TextView) v.findViewById(R.id.info3);
			TextView info4 = (TextView) v.findViewById(R.id.info4);
			int stub_visibility;
			if(la.extended)
				stub_visibility = info1.getVisibility();
			else
				stub_visibility = info3.getVisibility();
			
			if (stub_visibility == View.GONE) // invisibile
			{
				la.setExpanded(pos, true);
				info3.setVisibility(View.VISIBLE);
				info4.setVisibility(View.VISIBLE);
				if (la.extended) {
					info1.setVisibility(View.VISIBLE);
					info2.setVisibility(View.VISIBLE);
				}
			} else {
				la.setExpanded(pos, false);
				info3.setVisibility(View.GONE);
				info4.setVisibility(View.GONE);
				if (la.extended) {
					info1.setVisibility(View.GONE);
					info2.setVisibility(View.GONE);
				}
			}
		}
	}

	/**
	 * The choice that appear to the user depends on the notification so here
	 * the available choices are pushed into the menu
	 * 
	 * @author Aya Kamel
	 * @param v
	 *            The view of the chosen item
	 */
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenu.ContextMenuInfo menuInfo) {

		super.onCreateContextMenu(menu, v, menuInfo);
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;

		// Set menu look-and-feel parameters
		menu.setHeaderTitle(getString(R.string.options));
		//menu.setHeaderIcon(R.drawable.settings);

		String[] menuItems = getResources().getStringArray(R.array.popupMenu);

		// All notifications can be cancelled
		menu.add(0, AppConstants.MENU_CANCEL, 0, menuItems[0]);

		if (!db.isOpened)
			db.open();
		// Only requested outgoing notifications' status can be
		// accepted/rejected
		if (tab_id == AppConstants.TAB_OUTGOING) {
			if (db.isRequested(info.id)) {// This is a requested outgoing
											// notification

				// Alternate the accept and reject options such that the
				// appearing option is opposite to the current
				if (!db.isAccepted(info.id))
					menu.add(0, AppConstants.MENU_ACCEPT, 0, menuItems[1]);
				else
					menu.add(0, AppConstants.MENU_REJECT, 0, menuItems[2]);

			} else // This is an offered outgoing notification
			{
				menu.add(0, AppConstants.MENU_SAVE, 0, menuItems[3]);
			}
		} else // This is a self/incoming notification
		{
			menu.add(0, AppConstants.MENU_SAVE, 0, menuItems[3]);
		}
		db.close();

	}

	/**
	 * Inflates the options menu items
	 * 
	 * @author Aya Kamel
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.custom_menu, menu);
		return true;
	}

	/**
	 * Sets the on click listeners for all the menu items in the activity
	 * 
	 * @author Aya Kamel
	 * @see android.app.Activity#onMenuItemSelected(int, android.view.MenuItem)
	 */
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		Toast.makeText(this.getApplicationContext(),
				"slected " + item.getItemId(), Toast.LENGTH_SHORT);
		// Save the request on which the current selection will take place
		final AdapterContextMenuInfo req = (AdapterContextMenuInfo) item
				.getMenuInfo();
		if (!db.isOpened)
			db.open();
		switch (item.getItemId()) {
		// Create a new notification -- will direct to another list
		// case R.id.addMenuButton:
		// Intent i = new Intent();
		// i.setClass(getApplicationContext(), CreateRequest.class);
		// startActivity(i);
		// break;

		// redirects to New offer activity
		case R.id.NewOfferMenuButton:
			startActivity(new Intent(getApplicationContext(), CreateOffer.class));
			break;

		// Redirects to new request activity
		case R.id.NewRequestMenuButton:
			startActivity(new Intent(getApplicationContext(),
					CreateRequest.class));
			break;

		// Redirects to new Self-alarm activity
		case R.id.NewAlarmMenuButton:
			startActivity(new Intent(getApplicationContext(),
					CreateAlarm.class));
			break;

		// Refreshes the current tab
		case R.id.refreshMenuButton:
			ClientServerCommunication.getArrivals(this);
			ClientServerCommunication.getNewRequest(this);
			ClientServerCommunication.refreshIncomingNotifications(this);
			ClientServerCommunication.refreshOutgoingNotifications(this);
			ClientServerCommunication.refreshSelfNotifications(this);
			
			break;

		// Directs to the permissions activity
		case R.id.showPermissionMenuButton:
			startActivity(new Intent(getApplicationContext(),
					PermissionsActivity.class));
			break;

		// Directs to the permissions activity
		case R.id.showFafavouriteButton:
			startActivity(new Intent(getApplicationContext(),
					FavoriteNotificationsActivity.class));
			break;

		// Deletes the selected request
		case AppConstants.MENU_CANCEL:
			db.cancelNotification(req.id, tab_id);
			break;

		// Changes the state of the selected request to accepted
		case AppConstants.MENU_ACCEPT:
			db.setStatus(req.id, true);
			break;

		// Changes the state of the selected request to rejected
		case AppConstants.MENU_REJECT:
			db.setStatus(req.id, false);
			break;

		// Saves the selected request to the favorites database
		case AppConstants.MENU_SAVE:
			saveToFavorites(req.id);
			break;
		}
		db.close();
		return false;
	}

	/**
	 * Saves the notification of id to the favorites list
	 * 
	 * @author Aya Kamel
	 * @param id
	 *            The id of the notification to be saved
	 */
	private void saveToFavorites(long id) {
		// TODO Auto-generated method stub
		Log.i("Tracer", "Saving notification "+id+" to the favorites");
		if (!db.isOpened)
			db.open();

		Cursor c = db.fetchNotification(id, tab_id);
		if(c!= null && c.getCount() > 0)
		{
			
			String name = "";
			String phone = "";
			if(tab_id!=AppConstants.TAB_SELF) //In self phone is not significant
			{
				name = c.getString(c.getColumnIndex(AppConstants.CNAME));
				phone = c.getString(c.getColumnIndex(AppConstants.CPHONE));
			}
			else
			{
				name = getString(R.string.myself);
				phone = "";
			}
			String location = c.getString(c.getColumnIndex(AppConstants.LOCATION));
			String value = c.getString(c.getColumnIndex(AppConstants.VALUE));
			String type = c.getString(c.getColumnIndex(AppConstants.TYPE));
			db.addNotification(name, phone, location, value, type, tab_id);
		}
		else
		{
			Log.i("Tracer", "Something wrong with cursor");
		}
	
		db.close();
	}

	/**
	 * @author Aya Kamel
	 * @see android.app.Activity#onPause()
	 */
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		unregisterReceiver(icr);
	}

	/**
	 * @author Aya Kamel
	 * @see android.app.Activity#onResume()
	 */
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		if (icr != null)
			registerReceiver(icr, filter);
	}

	/**
	 * @author Aya Kamel
	 * @see android.app.Activity#onStop()
	 */
	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
	}

	/**
	 * Refreshes the table on data update
	 * 
	 * @author Aya Kamel
	 */
	private void refreshTables() {
		Log.i("Tracer", "Refreshing..");
		if (!db.isOpened)
			db.open();
		Cursor c1 = db.fetchAllNotifications(tab_id);
		la.changeCursor(c1);
		db.close();
	}

	/**
	 * A broadcast receiver to receive the broadcasts declaring that changes
	 * have been applied to the database
	 * 
	 * @author Aya Kamel
	 */
	public class IncomingReceiver extends BroadcastReceiver {

		/**
		 * The function that is called whenever a broadcast is received. If the
		 * broadcast is a call for updating the tables the list view is
		 * refreshed
		 * 
		 * @author Aya Kamel
		 * @see android.content.BroadcastReceiver#onReceive(android.content.Context,
		 *      android.content.Intent)
		 */
		@Override
		public void onReceive(Context arg0, Intent arg1) {
			// TODO Auto-generated method stub
			if (arg1.getAction().equals(AppConstants.UPDATE_TABLES)) 
				refreshTables();
		}

	}

}
